import { _decorator, Component, Vec3, v3, tween, Tween, Node, Quat, Camera, geometry, PhysicsSystem } from 'cc';
import { GameManager } from '../GameManager';
import { AimType } from '../Constant';
const { ccclass, property } = _decorator;

const v3_0 = v3();
const v = v3();
const quat_0: Quat = new Quat();

@ccclass('CameraController')
export class CameraController extends Component {

    private _targetAngles: Vec3 = v3();
    private _target: Node = null;
    private _rotationToEnemy: boolean = false;

    private shakeDuration: number = 0.5;
    private shakeIntensity: number = 0.3;
    private originalPosition: Vec3 = new Vec3();
    private shakeTime: number = 0;
    private isShaking: boolean = false;

    protected start(): void {
        // 记录摄像机的原始位置
        this.originalPosition.set(this.node.position);
    }

    LookAtTarget(node: Node) {
        this._rotationToEnemy = true;
        this._target = node;
    }

    Reset() {
        this._target = null;
        this._rotationToEnemy = false;
    }

    SetTargetAngle(x: number, y: number, z: number) {
        this._targetAngles.set(x, y, z);
    }

    Shake() {
        if (this.isShaking) return;

        this.isShaking = true;
        this.shakeTime = 0;
    }

    protected update(dt: number): void {
        if (!this.isShaking) return;
        this.shakeTime += dt;

        if (this.shakeTime >= this.shakeDuration) {
            // 晃动结束，恢复摄像机位置
            this.isShaking = false;
            this.node.position = this.originalPosition;
            return;
        }

        // 生成随机的摄像机偏移
        const offsetX = (Math.random() - 0.5) * 2 * this.shakeIntensity;
        const offsetY = (Math.random() - 0.5) * 2 * this.shakeIntensity;

        // 应用摄像机偏移
        this.node.position = new Vec3(this.originalPosition.x + offsetX, this.originalPosition.y + offsetY, this.originalPosition.z);
    }

    outRay = new geometry.Ray();
    lateUpdate(deltaTime: number) {
        if (this._rotationToEnemy && this._target) {
            Vec3.subtract(v, this._target.worldPosition, this.node.worldPosition);
            Quat.fromViewUp(quat_0, v.normalize());
            Quat.rotateY(quat_0, quat_0, Math.PI);
            Quat.lerp(quat_0, this.node.rotation, quat_0, 0.1);
            this.node.setRotation(quat_0);
        }

        if (GameManager.Instance.GameOver || this._rotationToEnemy) return;
        v3_0.set(this.node.parent.eulerAngles);
        Vec3.lerp(v3_0, v3_0, this._targetAngles, 0.5);
        this.node.parent.setRotationFromEuler(v3_0);
        let distance = 3;
        geometry.Ray.fromPoints(this.outRay, this.node.worldPosition.clone().add(this.node.forward), this.node.worldPosition.clone().subtract(this.node.forward));
        if (PhysicsSystem.instance.raycastClosest(this.outRay, AimType.ground, 10000000)) {
            const raycastClosestResult = PhysicsSystem.instance.raycastClosestResult;
            distance = raycastClosestResult.distance;
        }
        let z = distance - 1.5;
        if (z < 0.2) z = 0.2;
        if (z > 1.5) z = 1.5;
        if (Math.abs(this.node.position.z - z) > 0.1) {
            this.node.position.lerp(v3(0, z / 3.75, z), 0.05);
        }
    }
}